//分数规划
/**
    通过二分答案找到相应精度下的答案
    若有(a1, b1), (a2, b2), ...., (an, bn)
    那么假设选k组数据后答案是x，那么有
    (a1 + a2 + a3 + ... + an) / (b1 + b2 + .... + bn) = x
    所以a1 + a2 + .... + an - (b1 * x + b2 * x + b3 * x) = 0
    然后二分x
 */

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define endl '\n'

int inf = 0x3f3f3f3f3f3f3f3f;

void solve() {
    //模板题：洛谷P10505
    while (true) {
        int n, k;
        cin >> n >> k;
        if (n == 0 && k == 0) {
            break;
        }
        struct Node {
            int a, b;
        };
        vector<Node> arr(n);
        int sum = 0;
        for (int i = 0; i < n; i++) {
            cin >> arr[i].a;
            sum += arr[i].a;
        }
        for (int i = 0; i < n; i++) {
            cin >> arr[i].b;
        }
        auto f = [&](double x) {
            vector<double> temp;
            for (int i = 0; i < n; i++) {
                temp.push_back(arr[i].a - x * arr[i].b);
            }
            sort(temp.begin(), temp.end(), [&](double a, double b) -> bool {
                return a > b;
            });
            double res = 0;
            for (int i = 0; i < n - k; i++) {
                res += temp[i];
            }
            return res >= 0;
        };
        double l = 0, r = 120, ans = 0;
        while (abs(r - l) > 1e-6) {
            double mid = (l + r) / 2;
            // cout << "mid = " << mid << endl;
            if (f(mid)) {
                ans = mid;
                l = mid;
            }else {
                r = mid;
            }
        } 
        cout << (int)(round(100 * ans)) << endl;
    }
}

/**
 * 与01背包结合
 */
void solve1() {
    int n, w;
    cin >> n >> w;
    struct Node {
        int w, t;
    };
    vector<Node> arr(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> arr[i].w >> arr[i].t;
    }
    vector<double> dp(1010, -inf);
    auto f = [&](double x) {
        for (int i = 0; i <= 1000; i++) dp[i] = -inf;
        for (int i = 0; i <= min(1000LL, arr[1].w); i++) {
            dp[i] = arr[1].t - x * arr[1].w;
        }
        //这个一个注意点
        //大于等于0时是0，如果如果直接初始化可能为负数
        //01背包优化
        dp[0] = 0;
        for (int i = 2; i <= n; i++) {
            for (int j = 1000; j >= 0; j--) {
                dp[j] = max(dp[j], dp[max(0LL, j - arr[i].w)] + arr[i].t - x * arr[i].w);
            }
        }
        return (dp[w] + 1e-6) >= 0;
    };
    double l = 0, r = 1e13, ans = 0;
    while (abs(r - l) >= 1e-6) {
        double mid = (l + r) / 2;
        if (f(mid)) {
            ans = mid;
            l = mid;
        }else {
            r = mid;
        }
    }
    cout << (int)(ans * 1000 + 1e-7) << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t = 1;
    while (t--) solve1();
    return 0;
}